﻿using System;
using System.Windows.Forms;

namespace SyringeControl
{
    using WinForms;
    using System.Windows.Forms.Design;
    using System.ComponentModel.Design;
    using SyringeControl.ControlConfiguration.Events;
    using System.ComponentModel;
    using System.Collections.Generic;

    /// <summary>
    /// A form used to visualize a control, interact with it and modify its properties changes.
    /// </summary>
    public partial class MainForm : Form, IControlView
    {
        readonly IViewControlModel _model;
        /// <summary>
        /// initializes an instance of <see cref="SyringeControl.MainForm"/> class.
        /// </summary>
        public MainForm(IViewControlModel model)
        {
            InitializeComponent();
            _model = model;
            _model.BindList(controlList, m => m.Types)
                .CurrentValue(m => m.SelectedType)
                .Display(type => type.Name);
            _model.OnChange(m => m.TestedControl, this.SetControl);
            Load += new EventHandler(MainForm_Load);
        }

        void MainForm_Load(object sender, EventArgs e)
        {
            pgControlEditor.PropertyTabs.AddTabType(typeof(EventPropertyTab), System.ComponentModel.PropertyTabScope.Static);
        }

        void InvokeAssemblySelectionRequested()
        {
            var handler = AssemblySelectionRequested;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        void InvokeControlReloadRequested()
        {
            var handler = ControlReloadRequested;
            if (handler != null) handler(this, EventArgs.Empty);
        }

        void InvokeControlSetupRequested()
        {
            var handler = ControlSetupRequested;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
        #region Члены IControlView
        /// <summary>
        /// Event that is raised when user requests selecting new assembly.
        /// </summary>
        public event EventHandler AssemblySelectionRequested;
        /// <summary>
        /// Event that is raised when control under test needs to be recreated.
        /// </summary>
        public event EventHandler ControlReloadRequested;
        /// <summary>
        /// Event that is raised when user requests setting up tested controller.
        /// </summary>
        public event EventHandler ControlSetupRequested;
        /// <summary>
        /// Sets a control that is currently tested.
        /// </summary>
        /// <param name="control">currently tested control</param>
        [System.Security.Permissions.ReflectionPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted=true)]
        void SetControl(Control control)
        {
            var oldControl = (pgControlEditor.SelectedObject as Control);
            if (oldControl != null)
            {
                oldControl.Resize -= RecomputeControlLocation;
                panelHost.Controls.Remove(oldControl);
            }
            if (control != null)
            {
                control.Site = this.Site;
                panelHost.Controls.Add(control);
                control.Location = ComputeLocation(control.Size, panelHost.Size);
                control.Resize += RecomputeControlLocation;
                pgControlEditor.SelectedObject = control;
            }
        }

        void RecomputeControlLocation(object sender, EventArgs e)
        {
            var control = (pgControlEditor.SelectedObject as Control);
            if (control != null)
            {
                control.Location = ComputeLocation(control.Size, panelHost.Size);
            }
        }

        private System.Drawing.Point ComputeLocation(System.Drawing.Size controlSize, System.Drawing.Size hostSize)
        {
            var temp =  (hostSize - controlSize);
            return new System.Drawing.Point(temp.Width / 2, temp.Height / 2);
        }

        #endregion


        private void buttonLoad_Click(object sender, EventArgs e)
        {
            InvokeAssemblySelectionRequested();
        }

        private void buttonReloadControl_Click(object sender, EventArgs e)
        {
            InvokeControlReloadRequested();
        }

        private void buttonSetup_Click(object sender, EventArgs e)
        {
            InvokeControlSetupRequested();
        }
    }
}